//-----------------------------------------------------------------------------
//<filedescription file="RegExLibrary" company="Microsoft">
//  <copyright>
//     Copyright (c) 2005-2010, 2012 Microsoft Corporation.  All rights reserved.
//  </copyright>
//  <purpose>
//  </purpose>
//  <notes>
//  </notes>
//</filedescription>
//-----------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;

namespace SNSHelper.Common
{
    /// <summary>
    /// This class supports the Configuration Manager infrastructure and is not intended to be used directly from your code. Enumeration of the available Regular Expressions for the Configuration Manager console.
    /// </summary>
    public enum RegExExpression
    {
        /// <summary>
        /// An alpha numeric sequence of a-z,A-Z,0-9 only
        /// </summary>
        AlphaNumericOnly = 0,

        /// <summary>
        /// An alpha numeric space sequence of a-z,A-Z,0-9 only
        /// </summary>
        AlphaNumericWithSpace,

        /// <summary>
        /// a computer/server name (1-15 chars)
        /// </summary>
        ComputerName,

        /// <summary>
        /// A valid registry key for mobile devices has the same format as general registry key on PC, but it starts
        /// with following key-words, four acronyms in total 
        /// HKLM, HKCU, HKCR, HKU
        /// Notice: This DeviceRegistryKey is used for mobile devices only, for general registry, please use RegistryKey
        /// </summary>
        DeviceRegistryKey,

        /// <summary>
        /// A valid name for mobile devices has the same format as general name on PC, (2-15 chars) 
        /// Notice: This name is used for mobile devices only.
        /// </summary>
        DeviceName,

        /// <summary>
        /// a DNS Domain name e.g., www.microsoft.com (each label is up to 63 characters; the total length is up to 254 characters; cannot end with '.' or '-')
        /// </summary>
        DNSDomainName,

        /// <summary>
        /// a DNS Domain name e.g., microsoft (name is from 1 to 63 characters; cannot end with '-')
        /// </summary>
        DNSName,

        /// <summary>
        /// a Domain name i.e. Redmond or Fareast (1-15 chars)
        /// </summary>
        DomainName,

        /// <summary>
        /// a Domain name i.e. Redmond or Fareast (1-254 chars)
        /// </summary>
        LongDomainName,

        /// <summary>
        /// a domain group name i.e REDMOND\SQLServer2005SQLAgentUser$DBLab$MSSQLSERVER (domain name 1-15 chars, group name 1-128 chars)
        /// </summary>
        DomainGroupName,

        /// <summary>
        /// a domain user name i.e REDMOND\tester (domain name 1-15 chars, user name 1-20 chars)
        /// </summary>
        DomainUserName,

        /// <summary>
        /// a valid email address i.e somebody@microsoft.com
        /// </summary>
        EmailAddress,

        /// <summary>
        /// A valid file version e.g 1.2.3.4
        /// </summary>
        FileVersion,

        /// <summary>
        /// a valid folder name or a valid file name.
        /// </summary>
        FolderName,

        /// <summary>
        /// a valid file name
        /// </summary>
        FileName,

        /// <summary>
        /// A valid filename that may contain the filesystem wildcards "*" and/or "?".
        /// </summary>
        FileNameWithWildcards,

        /// <summary>
        /// A valid filename extension
        /// </summary>
        FileExtension,

        /// <summary>
        /// A valid UNC Path
        /// </summary>
        UNCPath,

        /// <summary>
        /// a valid fully qualified domain name  i.e. redmond.microsoft.com
        /// </summary>
        FullyQualifiedDomainName,

        /// <summary>
        /// a group user name i.e NT Authority
        /// </summary>
        GroupName,

        /// <summary>
        /// a group user name i.e NT Authority\tester
        /// </summary>
        GroupUserName,

        /// <summary>
        /// GUID i.e: 3231C820-C178-4c00-98BB-8C8A42C1FF04
        /// </summary>
        GUID,

        /// <summary>
        /// a valid number i.e. +123, 123, -123
        /// </summary>
        Integer,

        /// <summary>
        /// a command line to run eg. not ipconfig.exe /all
        /// </summary>
        InvalidCommandLine,

        /// <summary>
        /// invalid file type.(wildcards like * ? are ok eg *.log or a?c.txt)
        /// </summary>
        InvalidFileType,

        /// <summary>
        /// invalid location  ( %WinDir%, c:\Location are ok)
        /// </summary>
        InvalidLocation,

        /// <summary>
        /// invalid number
        /// </summary>
        InvalidNumber,

        /// <summary>
        /// a valid ip address i.e 255.255.255.0
        /// </summary>
        IPAddress,

        /// <summary>
        ///  a valid IPV6 Prefix
        /// FE80:0202:B3FF:FE1E
        /// XXXX:XXXX:XXXX:XXXX where [X]= [0-9A-Fa-f]
        /// </summary>
        IPV6Prefix,


        /// <summary>
        /// a valid local path e.g. c:\path
        /// </summary>
        LocalPath,

        /// <summary>
        /// a valid local path e.g. c:\path\test
        /// </summary>
        LocalFilePath,

        /// <summary>
        /// a valid local path, may contain '*' and '?'
        /// </summary>
        LocalFilePathWithWildcards,

        /// <summary>
        /// a valid local path with suffix e.g. c:\path\file.ext
        /// </summary>
        LocalFilePathWithSuffix,

        /// <summary>
        /// LDAP path i.e: LDAP://CN=Computers,DC=fareast,DC=corp,DC=microsoft,DC=com
        /// </summary>
        LdapPath,

        /// <summary>
        /// LDAP or GC path e.g. GC://CN=Computers,DC=fareast,DC=corp,DC=microsoft,DC=com
        /// </summary>
        LdapGcPath,

        /// <summary>
        /// a valid MAC address eg AABBCCDDEEFF
        /// </summary>
        MacAddress,

        /// <summary>
        /// A valid Msi version.
        /// </summary>
        MsiVersion,

        /// <summary>
        /// A valid Mac version.
        /// </summary>
        MacVersion,

        /// <summary>
        /// a valid network path e.g. \\server\path
        /// </summary>
        NetworkPath,

        /// <summary>
        /// a valid network path e.g. \\server\path or \\server\*
        /// </summary>
        NetworkPathAllowWildcard,

        /// <summary>
        /// a valid network path e.g. \\server\path\test
        /// </summary>
        NetworkFilePath,

        /// <summary>
        /// a valid network path with suffix e.g. \\server\path\file.ext
        /// </summary>
        NetworkFilePathWithSuffix,

        /// <summary>
        /// a valid network path e.g. \\server\path without ending backslash
        /// </summary>
        NetworkPathWithoutEndingBackslash,

        /// <summary>
        /// One letter from a-z and A-Z
        /// </summary>
        OneLetter,

        /// <summary>
        /// Organization Unit, e.g. LDAP://OU=abc,DC=abcd
        /// </summary>
        OrganizationUnit,

        /// <summary>
        /// organization Unit without prefix, e g CN=xx,OU=xx,DC=xx
        /// </summary>
        OrganizationUnitWithoutPrefix,

        /// <summary>
        /// a valid Product Key
        /// </summary>
        ProductKey,

        /// <summary>
        /// a valid Port Number
        /// </summary>
        PortNumber,

        /// <summary>
        /// a valid registry key,similar to the file path except starting with 
        /// HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER or HKEY_CLASSES_ROOT or HKEY_USERS 
        /// HKEY_PERFORMANCE_DATA or HKEY_CURRENT_CONFIG or HKEY_DYN_DATA etc.
        /// </summary>
        RegistryKey,

        /// <summary>
        /// a valid registry key without prefix like HKEY_LOCAL_MACHINE etc
        /// </summary>
        RegistryKeyWithoutPrefix,

        /// <summary>
        /// a valid relative path
        /// </summary>
        RelativePath,

        /// <summary>
        /// a valid SMTP server name i.e: somemachine.domain1.domain2, somemachine, 
        /// 123.255.255.255:port, [2001:4898:2c:b:2966:344e:c56f:3ea0]:port
        /// </summary>
        SmtpServerName,

        /// <summary>
        /// A valid software update group name, it doesn't contains #, ? \ . and /  
        /// </summary>
        SoftwareUpdateGroupName,

        /// <summary>
        /// A valid T-Sql statement
        /// </summary>
        SqlStatement,

        /// <summary>
        /// Instance names are limited to 16 characters.
        /// The first character in the instance name must be a letter, an ampersand (&), an underscore (_), or a number sign (#). 
        /// Acceptable letters are those defined by the Unicode Standard 2.0, which includes Latin characters a-z and A-Z, 
        /// in addition to letter characters from other languages. 
        /// Subsequent characters can be: 
        /// Letters as defined in the Unicode Standard 2.0.
        /// Decimal numbers from either Basic Latin or other national scripts. 
        /// The dollar sign ($), a number sign (#), or an underscore (_). 
        /// </summary>
        SqlInstanceName,

        /// <summary>
        /// Currently, it simply meets account name format, e.g. devicesGroup
        /// </summary>
        UniversalSecurityGroup,

        /// <summary>
        /// a valid unsigned integer
        /// </summary>
        UnsignedInteger,

        /// <summary>
        /// a valid user name, 1-20 chars, and not containing illegal chars eg. ralph 
        /// </summary>
        UserName,

        /// <summary>
        /// a valid user folder or search folder name
        /// </summary>
        UserFolderName,

        /// <summary>
        /// a valid URL defined in rfc1738
        /// <example>ftp://user:password@ftp.site.com:23/dir/output.bin?file=source&amp;#header</example>
        /// </summary>
        URL,

        /// <summary>
        /// Variable named value(%var%): Alpha-numeric, underscore (_) and dash (-), No embedded space 
        /// </summary>
        VariableNamedValue,

        /// <summary>
        /// Variable names: Alpha-numeric, underscore (_) and dash (-), No embedded space
        /// </summary>
        VariableNames,

        /// <summary>
        /// Read-Only Variable names: Alpha-numeric, underscore (_) and dash (-), No embedded space, and should begin with underscore
        /// </summary>
        VariableNamesReadOnly,

        /// <summary>
        /// a valid work group is 1-15 characters and can not contain ; : " gtr lsr * + = \ | ?
        /// </summary>
        WorkGroupName,

        /// <summary>
        /// A valid Wql WHERE clause
        /// </summary>
        WqlWhereClause,

        /// <summary>
        /// A valid local drive without backslash. for example a:
        /// </summary>
        LocalDriveWithoutBackslash,

        /// <summary>
        /// a strong password, Contains 7-bit ASCII characters, in the range of 32-126, excluding ':', ',' and '"' characters.
        /// String length is limited to 32 characters.
        /// Limitations:
        /// 1. Password Length: Passwords must be at least 8 characters long.
        /// 2. Password Complexity: Password must include:
        ///     a. At least one Digit character ('0', '1',...'9')
        ///     b. At least one 7-bit ASCII non alpha-numeric character, above 0x20,(e.g. '!', '$', ';'). Note that "_" is considered alphanumeric.
        ///     c. Both lower-case Latin ('a', 'b',..., 'z') and upper case Latin ('A', 'B', ..., 'Z').
        /// </summary>
        StrongPassword,

        /// <summary>
        /// a valid user account of qualified domain name i.e: nanw.ds.army.mil\SVC.SMSDOIM4.LEWI
        /// The length of FQDN is 255 and the user name 20.
        /// </summary>
        FullyQualifiedDomainUserName,

        /// <summary>
        /// a valid sccm site code, string length is 3, and all of the charactors are AlphaNumericOnly.
        /// </summary>
        SccmSiteCode,

        /// <summary>
        /// invalid cross platform location  ( /opt/location, c:\Location are ok)
        /// </summary>
        InvalidCrossPlatformLocation,
    }

    /// <summary>
    /// This class supports the Configuration Manager infrastructure and is not intended to be used directly from your code. Commonly used regular expressions in the Configuration Manager Console.
    /// </summary>
    public static class RegExLibrary
    {
        private static SortedList<string, string> regExRepository;

        /// <summary>
        /// Gets or sets the list of expressions within the RegExLibrary.
        /// </summary>
        public static SortedList<string, string> ExpressionList
        {
            get { return regExRepository; }
            set { regExRepository = value; }
        }

        /// <summary>
        /// Retrieves a regular expression from the library.
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        public static string GetRegularExpression(RegExExpression exp)
        {
            //there should be no cases where the expression does not exist
            System.Diagnostics.Debug.Assert(regExRepository.ContainsKey(exp.ToString()) == true);

            return regExRepository[exp.ToString()];
        }

        /// <summary>
        /// build the regEx library 
        /// </summary>
        static RegExLibrary()
        {
            regExRepository = new SortedList<string, string>();

            AddRegularExpression(RegExExpression.AlphaNumericOnly, @"^[A-Za-z0-9]+$");
            AddRegularExpression(RegExExpression.AlphaNumericWithSpace, @"^([A-Za-z0-9]|([A-Za-z0-9][A-Za-z0-9 ]*[A-Za-z0-9]))$");
            AddRegularExpression(RegExExpression.ComputerName, @"^[^~!@#$\^&*\(\){}\\\|;:'"",.<>\/? ]{1,15}$");
            AddRegularExpression(RegExExpression.DeviceRegistryKey, @"^(HKCU|HKLM|HKCR|HKU)([\\][^\\/:*?""<>|\r\n]+)*[\\]?$");
            AddRegularExpression(RegExExpression.DeviceName, @"^[A-Za-z0-9]*(([A-Za-z0-9]+\-[A-Za-z0-9]*)+[A-Za-z0-9]|[A-Za-z]+)[A-Za-z0-9]*$");
            AddRegularExpression(RegExExpression.DNSName, @"(?=^.{1,63}$)(^(?:(?!\d|-)[a-zA-Z\d\-]{1,63}(?<!-))$)");
            AddRegularExpression(RegExExpression.DNSDomainName, @"(?=^.{1,255}$)(^(?:(?!\d|-)[a-zA-Z\d\-]{1,63}(?<!-)\.)(?:(?!\d|-)[a-zA-Z\d\-]{1,63}(?<!-)\.)*(?:(?!\d|-)[a-zA-Z\d\-]{1,63}(?<!-))$)");
            AddRegularExpression(RegExExpression.DomainName, @"^[^\\/""\[\]:; |=,+*?<>]{1,15}$");
            AddRegularExpression(RegExExpression.LongDomainName, @"^[^\\/""\[\]:; |=,+*?<>]{1,255}$");
            AddRegularExpression(RegExExpression.DomainGroupName, @"^[^\]\\"" /\[:;|=,+*?<>]{1,15}\\[^\]\\""/\[:;|=,+*?<>]{1,128}(?<=[^\s])$");
            AddRegularExpression(RegExExpression.DomainUserName, @"^[^\]\\"" /\[:;|=,+*?<>]{1,15}\\[^\]\\""/\[:;|=,+*?<>]{1,20}(?<=[^\s])$");
            AddRegularExpression(RegExExpression.EmailAddress, @"^[^\\/""\[\]:; |=,+*?<>]+@[^\\/""\[\]:; |=,+*?<>]+\.[a-zA-Z]{2,15}$");
            AddRegularExpression(RegExExpression.FileName, @"^[^/\\:*?""<>|\r\n]{1,255}$");
            AddRegularExpression(RegExExpression.FileExtension, @"^\.[^/\\:*?""<>|\r\n]{1,254}$");
            AddRegularExpression(RegExExpression.FileNameWithWildcards, @"^[^/\\:""<>|\r\n]{1,255}$");
            AddRegularExpression(RegExExpression.FileVersion, @"^[0-9]+.[0-9]+.[0-9]+.[0-9]+$|^[0-9]+.[0-9]+$");
            AddRegularExpression(RegExExpression.FolderName, @"^[^/:*?""<>|\r\n]{1,244}$");
            AddRegularExpression(RegExExpression.FullyQualifiedDomainName, @"(?=^.{1,255}$)^([a-zA-Z\d\-_]{1,63}\.)+[a-zA-Z\d\-_]{1,63}$");
            AddRegularExpression(RegExExpression.FullyQualifiedDomainUserName, @"(?=^.{1,275}$)^([a-zA-Z\d\-_]{1,63}\.)+[a-zA-Z\d\-_]{1,63}\\[^\]\\""/\[:;|=,+*?<>]{1,20}(?<=[^\s])$");
            AddRegularExpression(RegExExpression.GroupName, @"^[^\]\\""/\[:;|=,+*?<>]{1,128}$");
            AddRegularExpression(RegExExpression.GroupUserName, @"^[^\]\\""/\[:;|=,+*?<>]{1,128}\\[^\]\\""/\[:;|=,+*?<>]{1,256}(?<=[^\s])$");
            AddRegularExpression(RegExExpression.GUID, @"^(([0-9a-fA-F]{32})|([0-9a-fA-F]{8}([-][0-9a-fA-F]{4}){3}[-][0-9a-fA-F]{12})|([{][0-9a-fA-F]{8}([-][0-9a-fA-F]{4}){3}[-][0-9a-fA-F]{12}[}]))$");
            AddRegularExpression(RegExExpression.Integer, @"^[0-9]*$");
            AddRegularExpression(RegExExpression.InvalidCommandLine, @"[\\/:*?""<>|]+");
            AddRegularExpression(RegExExpression.InvalidFileType, @"[/:\\<>|""]");
            AddRegularExpression(RegExExpression.InvalidLocation, @"[""/<>|]");
            AddRegularExpression(RegExExpression.InvalidNumber, @"[^0-9]");
            AddRegularExpression(RegExExpression.IPAddress, @"(^((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9]{1})|([0-9]))(([.]((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([1-9][0-9]{1})|([0-9]))){3})$)");
            AddRegularExpression(RegExExpression.IPV6Prefix, @"^(([0-9A-Fa-f]{4}:){3}[0-9A-Fa-f]{4}$)");
            //                                                                      1) Max Len: 3-247            2) Folder Len: 1-244  3) Allow \ End          4) Variable Name Len: 1-259
            AddRegularExpression(RegExExpression.LocalPath, @"(^(?=^.{3,247}$)[a-zA-Z]:(\\[^\\/:*?""<>|]{1,244})*\\?$)|(^(?=^.{3,503}$)(%[^\\/:*?""<>]{1,259}%)(\\[^\\/:*?""<>|]{1,244})*\\?$)");
            
            //                                                                      1) Max Len: 3-247            2) Folder Len: 1-244  3) Allow \ End          4) Allow . and *    5) Variable Name Len: 1-259
            AddRegularExpression(RegExExpression.LocalFilePathWithWildcards, @"(^(?=^.{3,247}$)[a-zA-Z]:(\\[^\\/:""<>|]{1,244})*\\?$)|(^(?=^.{3,503}$)(%[^\\/:""<>]{1,259}%)(\\[^\\/:""<>|]{1,244})*\\?$)");
            
            //                                                                      1) Max Len: 4-258.            2)Folder Len: 1-244      3)FileName Len 1-255  4)No . End                   5)Variable Name 1-259
            AddRegularExpression(RegExExpression.LocalFilePath, @"(^(?=^.{4,258}$)[a-zA-Z]:(\\[^\\/:*?""<>|]{1,244})*\\[^\\/:*?""<>|]{1,255}(?<=[^.])$)|(^(?=^.{5,514}$)(%[^\\/:*?""<>]{1,259}%)(\\[^\\/:*?""<>|]{1,244})*\\[^\\/:*?""<>|]{1,255}(?<=[^.])$)");

            //                                                                      1) Max Len: 6-258             2)Folder Len: 1-244      3)FileName Len 1-253    4)Suffix       5)No . End                 5)Variable Name: 1-259
            AddRegularExpression(RegExExpression.LocalFilePathWithSuffix, @"(^(?=^.{6,258}$)[a-zA-Z]:(\\[^\\/:*?""<>|]{1,244})*\\[^\\/:*?""<>|]{1,253}[.][^\\/:*?""<>|]+(?<=[^.])$)|(^(?=^.{7,514}$)(%[^\\/:*?""<>]{1,259}%)(\\[^\\/:*?""<>|]{1,244})*\\[^\\/:*?""<>|]{1,253}[.][^\\/:*?""<>|]+(?<=[^.])$)");

            AddRegularExpression(RegExExpression.LdapPath, @"^([lL][dD][aA][pP]):\/\/([^\\/""\[\]:; |=,+*?<>]{0,255}(:[0-9]{1,5})?)?([\/]?([a-zA-Z]{1,2}=.{1,64},){0,}([a-zA-Z]{1,2}=.{1,64})?)?$");
            AddRegularExpression(RegExExpression.LdapGcPath, @"^(([lL][dD][aA][pP])|([gG][cC])):\/\/([^\\/""\[\]:; |=,+*?<>]{0,255}(:[0-9]{1,5})?)?([\/]?([a-zA-Z]{1,2}=.{1,64},){0,}([a-zA-Z]{1,2}=.{1,64})?)?$");
            AddRegularExpression(RegExExpression.MacAddress, @"^((([0-9a-fA-F]{2}){6})|((([0-9a-fA-F]{2})[:]){5}([0-9a-fA-F]{2}))|((([0-9a-fA-F]{2})[-]){5}([0-9a-fA-F]{2})))$");

            //FileVersion is insufficient for validating Msi Version. 
            //See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/version.asp
            //The expression below is still technically insufficient, but more closely approximates the desired rule.
            // BUG FIX:204072
            AddRegularExpression(RegExExpression.MsiVersion, @"^[0-9]+(.[0-9]+){0,7}$");

            //
            AddRegularExpression(RegExExpression.MacVersion, @"^[0-9]+(.[0-9]+){0,7}$");

            //                                                                              1) Computer/Domain/IP/IPV6/FQDN Name:1-255    2)Share Folder:1-244   3) Allow \ End
            AddRegularExpression(RegExExpression.UNCPath, @"^(?=^.{5,503}$)\\\\[^\\/""\[\]; |=,+*?<>]{1,255}(\\[^\\/:*?""<>|]{1,244})*[\\]?$");

            //                                                                              1) Computer/Domain/IP/IPV6/FQDN Name:1-255    2)Share Folder:1-244   3) Allow \ End
            AddRegularExpression(RegExExpression.NetworkPath, @"^(?=^.{5,503}$)\\\\[^\\/""\[\]; |=,+*?<>]{1,255}(\\[^\\/:*?""<>|]{1,244})+[\\]?$");
            
            //                                                                              1) Computer/Domain/IP/IPV6/FQDN Name:1-255    2)Share Folder:1-244   3) Allow \ or \* End
            AddRegularExpression(RegExExpression.NetworkPathAllowWildcard, @"^(?=^.{5,503}$)\\\\[^\\/""\[\]; |=,+*?<>]{1,255}(\\[^\\/:?""<>|]{1,244})+[\\]?$");

            //                                                                              1) Computer/Domain/IP/IPV6/FQDN Name:1-255    2)Share Folder:1-244   3) not Allow \ End
            AddRegularExpression(RegExExpression.NetworkPathWithoutEndingBackslash, @"^(?=^.{5,503}$)\\\\[^\\/""\[\]; |=,+*?<>]{1,255}(\\[^\\/:*?""<>|]{1,244})+$");

            //                                                                              1) Computer/Domain/IP/IPV6/FQDN Name:1-255    2)Share Folder:1-244      3)FileName: 1-255    4) No . End
            AddRegularExpression(RegExExpression.NetworkFilePath, @"^(?=^.{7,513}$)\\\\[^\\/""\[\]; |=,+*?<>]{1,255}(\\[^\\/:*?""<>|]{1,244})+\\[^\\/:*?""<>|]{1,255}(?<=[^.])$");

            //                                                                              1) Computer/Domain/IP/IPV6/FQDN Name:1-255    2)Share Folder:1-244      3)FileName: 1-253       4) Suffix
            AddRegularExpression(RegExExpression.NetworkFilePathWithSuffix, @"^(?=^.{9,513}$)\\\\[^\\/""\[\]; |=,+*?<>]{1,255}(\\[^\\/:*?""<>|]{1,244})+\\[^\\/:*?""<>|]{1,253}[.][^\\/:*?""<>|]+(?<=[^.])$");


            AddRegularExpression(RegExExpression.OneLetter, @"^[a-zA-Z]$");
            AddRegularExpression(RegExExpression.OrganizationUnit, @"^(LDAP://)?OU=(.+,([ \t])*dc=.+)+$");
            AddRegularExpression(RegExExpression.OrganizationUnitWithoutPrefix, @"^((CN=.+,)*(OU=.+,)*(DC=.+[,]*)+)$");
            AddRegularExpression(RegExExpression.ProductKey, @"(^$)|(^[0-9a-zA-Z]{5}-[0-9a-zA-Z]{5}-[0-9a-zA-Z]{5}-[0-9a-zA-Z]{5}-[0-9a-zA-Z]{5}$)|(^.{30,65535}$)|(^%\w{1,255}%$)");
            AddRegularExpression(RegExExpression.PortNumber, @"^(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[1-9])$");
            AddRegularExpression(RegExExpression.RegistryKey, @"^(HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE|HKEY_CLASSES_ROOT|HKEY_USERS|HKEY_PERFORMANCE_DATA|HKEY_CURRENT_CONFIG|HKEY_DYN_DATA)([\\][^\\\r\n]+)*[\\]?$");
            AddRegularExpression(RegExExpression.RegistryKeyWithoutPrefix, @"^([^\\\r\n]+)(\\[^\\\r\n]+)*$");
            AddRegularExpression(RegExExpression.RelativePath, @"^\\?\w[^\\/:*?""<>|]*(\\(\w[^\\/:*?""<>|]*))*$");
            AddRegularExpression(RegExExpression.SccmSiteCode, @"^[A-Z0-9]{3}$");
            AddRegularExpression(RegExExpression.SmtpServerName, @"^[^~!@#$\^&*\(\){}\\\|;'"",<>\/? ]+$");
            AddRegularExpression(RegExExpression.SoftwareUpdateGroupName, @"^[^\\/?.#]{1,256}$");
            AddRegularExpression(RegExExpression.SqlInstanceName, @"^[\w&_#][\w$#_]{0,15}$");
            AddRegularExpression(RegExExpression.SqlStatement, @"^([^\/:?<>|])*$");
            AddRegularExpression(RegExExpression.UniversalSecurityGroup, @"^[^~!@#$\^&*\(\){}\\\|;:'"",.<>\/?]+$");
            AddRegularExpression(RegExExpression.UnsignedInteger, @"^[0-9]+$");
            AddRegularExpression(RegExExpression.UserName, @"^[^\\/""\[\]:; |=,+*?<>]{1,20}$");
            AddRegularExpression(RegExExpression.UserFolderName, @"^[^\\/:*?""<>|\r\n]{1,125}$");
            AddRegularExpression(RegExExpression.URL, @"^([a-zA-z]+://)?(([0-9a-zA-Z])+:([0-9a-zA-Z])+@)?([0-9a-zA-Z]+(-[0-9a-zA-Z]+)*)(\.([0-9a-zA-Z]+(-[0-9a-zA-Z]+)*))*(:(\d)+)?([/][^/\s]+)*[/]?$");
            AddRegularExpression(RegExExpression.VariableNamedValue, @"^(?=^.{1,255}$)%(([_][-]*)*[A-Za-z0-9][A-Za-z0-9_-]*)%$");  //BUG: 124244 get document
            AddRegularExpression(RegExExpression.VariableNames, @"^(?=^.{1,255}$)([A-Za-z0-9][A-Za-z0-9_-]*)$");  //BUG: 124244 get document, BUG:140013
            AddRegularExpression(RegExExpression.VariableNamesReadOnly, @"^(?=^.{1,255}$)(([_][-]*)+[A-Za-z0-9][A-Za-z0-9_-]*)$");  //BUG: 136528 get document
            AddRegularExpression(RegExExpression.WorkGroupName, @"^[^\\"":;|=+*?<>]{1,15}$");
            AddRegularExpression(RegExExpression.WqlWhereClause, @"^([^\\/:*?""<>|\r\n])*$");
            AddRegularExpression(RegExExpression.LocalDriveWithoutBackslash, @"^([a-zA-Z]:)$");
            AddRegularExpression(RegExExpression.StrongPassword, @"^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^0-9a-zA-Z_])[\x23-\x2B\x2D-\x39\x3B-\x7E! ]{8,32}$");
            AddRegularExpression(RegExExpression.InvalidCrossPlatformLocation, @"[""<>|]");


#if (DEBUG)
            //verify library integrity
            foreach (RegExExpression value in Enum.GetValues(typeof(RegExExpression)))
            {
                try
                {
                    string test = regExRepository[value.ToString()];
                }
                catch (Exception)
                {
                    throw new NotImplementedException("RegExExpression " + value.ToString() + " not present in library");
                }
            }
#endif

        }

        /// <summary>
        /// add a regular expression to the library. The library keeps it as a string-string
        /// mapping to be compatible with the validationRuleManager. but in code, we use
        /// the enumeration for ease of use.
        /// </summary>
        /// <param name="exp">The exp.</param>
        /// <param name="p">The p.</param>
        private static void AddRegularExpression(RegExExpression exp, string p)
        {
            regExRepository.Add(exp.ToString(), p);
        }
    }
}
